//
// MSRangeSlider.m
//
// Created by Maksym Shcheglov on 2015-05-07.
// Copyright (c) 2015 Maksym Shcheglov.
// License: http://opensource.org/licenses/MIT
//

#import "XYRangeSlider.h"
#import "XYRangeSliderButton.h"
//#import "UIControl+HitTestEdgeInsets.h"

static CGFloat const kRangeSliderTrackHeight = 5;
static CGFloat const kRangeSliderDimension = 32;
static CGFloat const kThumbViewEdgeInset = -7.5f;

@interface XYRangeSlider ()

@property (nonatomic, strong) CALayer *trackLayer;
@property (nonatomic, strong) CALayer *selectedTrackLayer;

@property (nonatomic, strong) XYRangeSliderButton * fromThumbView;
@property (nonatomic, strong) XYRangeSliderButton * toThumbView;

@end

@implementation XYRangeSlider

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self ms_init];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self ms_init];
    }
    return self;
}

- (CGSize)intrinsicContentSize {
    return CGSizeMake(UIViewNoIntrinsicMetric, kRangeSliderDimension);
}

- (void)layoutSubviews {
    [self ms_updateThumbs];
    [self ms_updateTrackLayers];
}

- (void)setFromValue:(CGFloat)fromValue {
    _fromValue = fromValue;
    [self ms_alignValues];
    [self setNeedsLayout];
}

- (void)setToValue:(CGFloat)toValue {
    _toValue = toValue;
    [self ms_alignValues];
    [self setNeedsLayout];
}

- (void)setMinimumValue:(CGFloat)minimumValue {
    _minimumValue = minimumValue;
    [self ms_alignValues];
    [self setNeedsLayout];
}

- (void)setMaximumValue:(CGFloat)maximumValue {
    _maximumValue = maximumValue;
    [self ms_alignValues];
    [self setNeedsLayout];
}

- (void)setMinimumInterval:(CGFloat)minimumInterval {
    _minimumInterval = minimumInterval;
    [self ms_alignValues];
    [self setNeedsLayout];
}

- (void)setSelectedTrackTintColor:(UIColor *)selectedTrackTintColor {
    NSParameterAssert(selectedTrackTintColor);
    _selectedTrackTintColor = selectedTrackTintColor;
    self.selectedTrackLayer.backgroundColor = selectedTrackTintColor.CGColor;
}

- (void)setTrackTintColor:(UIColor *)trackTintColor {
    NSParameterAssert(trackTintColor);
    _trackTintColor = trackTintColor;
    self.trackLayer.backgroundColor = trackTintColor.CGColor;
}

#pragma mark - Private methods

- (void)ms_init
{
    _minimumValue = 0.0;
    _maximumValue = 1.0;
    _minimumInterval = 0.1;
    _fromValue = _minimumValue;
    _toValue = _maximumValue;
//    self.hitTestEdgeInsets = UIEdgeInsetsMake(kThumbViewEdgeInset, kThumbViewEdgeInset, kThumbViewEdgeInset, kThumbViewEdgeInset);

    _selectedTrackTintColor = [UIColor colorWithRed:0.0 green:122.0 / 255.0 blue:1.0 alpha:1.0];
    _trackTintColor = [UIColor colorWithRed:0.7 green:0.7 blue:0.7 alpha:1.0];

    self.trackLayer = [CALayer layer];
    self.trackLayer.backgroundColor = self.trackTintColor.CGColor;
    self.trackLayer.cornerRadius = 1.3;
    [self.layer addSublayer:self.trackLayer];

    self.selectedTrackLayer = [CALayer layer];
    self.selectedTrackLayer.backgroundColor = self.selectedTrackTintColor.CGColor;
    self.selectedTrackLayer.cornerRadius = 1.3;
    [self.layer addSublayer:self.selectedTrackLayer];

    self.fromThumbView = [[XYRangeSliderButton alloc] init];
//    self.fromThumbView.hitTestEdgeInsets = UIEdgeInsetsMake(kThumbViewEdgeInset, kThumbViewEdgeInset, kThumbViewEdgeInset, 0);
    [self.fromThumbView.panGestureRecognizer addTarget:self action:@selector(ms_didPanFromThumbView:)];
    [self addSubview:self.fromThumbView];

    self.toThumbView = [[XYRangeSliderButton alloc] init];
//    self.toThumbView.hitTestEdgeInsets = UIEdgeInsetsMake(kThumbViewEdgeInset, 0, kThumbViewEdgeInset, kThumbViewEdgeInset);
    [self.toThumbView.panGestureRecognizer addTarget:self action:@selector(ms_didPanToThumbView:)];
    [self addSubview:self.toThumbView];
}

- (void)ms_alignValues
{
    _minimumValue = MIN(self.maximumValue, self.minimumValue);
    _maximumValue = MAX(self.maximumValue, self.minimumValue);
    _minimumInterval = MIN(self.minimumInterval, self.maximumValue - self.minimumValue);
    _toValue = MIN(MAX(self.toValue, self.fromValue + self.minimumInterval), self.maximumValue);
    _fromValue = MAX(MIN(self.fromValue, self.toValue - self.minimumInterval), self.minimumValue);
}

- (void)ms_updateThumbs {
    CGPoint fromThumbLocation = [self ms_thumbLocationForValue:self.fromValue];
    self.fromThumbView.frame = CGRectMake(fromThumbLocation.x, fromThumbLocation.y, kRangeSliderDimension, kRangeSliderDimension);

    CGPoint toThumbLocation = [self ms_thumbLocationForValue:self.toValue];
    self.toThumbView.frame = CGRectMake(toThumbLocation.x + kRangeSliderDimension, toThumbLocation.y, kRangeSliderDimension, kRangeSliderDimension);
}

- (void)ms_updateTrackLayers {
    CGFloat width = CGRectGetWidth(self.bounds);
    CGFloat height = CGRectGetHeight(self.bounds);

    self.trackLayer.bounds = CGRectMake(0, 0, width - kRangeSliderDimension / 2 - kRangeSliderDimension / 2, kRangeSliderTrackHeight);
    self.trackLayer.position = CGPointMake(width / 2, height / 2);

    CGFloat from = self.fromThumbView.center.x;
    CGFloat to = self.toThumbView.center.x;

    [CATransaction begin];
    [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
    self.selectedTrackLayer.bounds = CGRectMake(0, 0, to - from, kRangeSliderTrackHeight);
    self.selectedTrackLayer.position = CGPointMake((from + to) / 2, height / 2);
    [CATransaction commit];
}

- (void)ms_didPanFromThumbView:(UIPanGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer.state != UIGestureRecognizerStateBegan && gestureRecognizer.state != UIGestureRecognizerStateChanged) {
        return;
    }

    CGPoint translation = [gestureRecognizer translationInView:self];
    [gestureRecognizer setTranslation:CGPointZero inView:self];
    CGFloat fromValue = [self ms_applyTranslation:translation.x forValue:self.fromValue];
    self.fromValue = MAX(MIN(fromValue, self.toValue - self.minimumInterval), self.minimumValue);
    if (self.delegate && [self.delegate respondsToSelector:@selector(rangeSlider:didChangeFromValue:)]) {
        [self.delegate rangeSlider:self didChangeFromValue:self.fromValue];
    }

//    [self sendActionsForControlEvents:UIControlEventValueChanged];
}

- (void)ms_didPanToThumbView:(UIPanGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer.state != UIGestureRecognizerStateBegan && gestureRecognizer.state != UIGestureRecognizerStateChanged) {
        return;
    }

    CGPoint translation = [gestureRecognizer translationInView:self];
    [gestureRecognizer setTranslation:CGPointZero inView:self];
    CGFloat toValue = [self ms_applyTranslation:translation.x forValue:self.toValue];
    self.toValue = MIN(MAX(toValue, self.fromValue + self.minimumInterval), self.maximumValue);
    if (self.delegate && [self.delegate respondsToSelector:@selector(rangeSlider:didChangeToValue:)]) {
        [self.delegate rangeSlider:self didChangeToValue:self.toValue];
    }
    
//    [self sendActionsForControlEvents:UIControlEventValueChanged];
}

- (CGFloat)ms_applyTranslation:(CGFloat)translation forValue:(CGFloat)value {
    CGFloat width = CGRectGetWidth(self.bounds) - 2 * kRangeSliderDimension;
    CGFloat valueRange = (self.maximumValue - self.minimumValue);

    return value + valueRange * translation / width;
}

- (CGPoint)ms_thumbLocationForValue:(CGFloat)value {
    CGFloat width = CGRectGetWidth(self.bounds) - 2 * kRangeSliderDimension;
    CGFloat height = CGRectGetHeight(self.bounds);
    CGFloat valueRange = (self.maximumValue - self.minimumValue);

    CGFloat x = valueRange == 0 ? 0 : width * (value - self.minimumValue) / valueRange;

    return CGPointMake(x, (height - kRangeSliderDimension) / 2);
}

- (void)setFromBackgroundImage:(UIImage *)fromBackgroundImage {
    [self.fromThumbView setBackgroundImage:fromBackgroundImage];
}

- (void)setToBackgroundImage:(UIImage *)toBackgroundImage {
    [self.toThumbView setBackgroundImage:toBackgroundImage];
}

@end
